package processes;

import java.util.ArrayList;

import factory.ObserverManager;

import DAO.ProductDAO;
import to.OrderTO;
import to.ProductTO;
import util.DateUtil;
import util.ProductParser;

public abstract class Machine extends Thread{
	private int baseDuration;
	private int durationRange;
	protected MachineManager machineManager;
	private static Object thread;
	private String machineId;
	private boolean running;
	private String lineName;
	protected ProductTO currentProduct;
	protected OrderTO work;
	protected ProductDAO dao = ProductDAO.getInstance();
	private long startTime;
	
	public Machine(int baseDuration, int durationRange, MachineManager machineManager, String machineId) {
		super();
		this.baseDuration = baseDuration;
		this.durationRange = durationRange;
		this.machineManager = machineManager;
		this.machineId = machineId;
		this.startTime = DateUtil.getInstance().getCurrentTimeLong();
	}
	
	public void addWork(OrderTO work){
		this.work = work;
		this.startTime = DateUtil.getInstance().getCurrentTimeLong();
		if(running==false){
			running=true;
			this.start();
		}
	}
	
	protected String getMachineId(){
		return machineId;
	}
	
	protected void setLineName(String lineName){
		this.lineName = lineName;
	}
	
	public String getLineName(){
		return lineName;
	}
	
	public OrderTO getWork(){
		return work;
	}
	
	public long getStartTime(){
		return startTime;
	}
	
	public void run() {
		while(true){
			//전처리
			currentProduct = bindProduct();
			System.out.println(machineId + " : " + currentProduct);
			if(currentProduct!=null){
				
				beforeManufacture();
				
				try {
					sleep(generateDuration());
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				//후처리
				afterManufacture();
				currentProduct = null;
				ObserverManager.getInstance().notifyDeploy();
				
			}else{
				this.stop();
				running=false;
			}
		}
	}
	
	protected ProductTO bindProduct(){
		if(work==null){
			return null;
		}
		ProductTO product = null;
		ArrayList<ProductTO> productList = work.getProductList();
		int i=0;
		for(i=0; i<=productList.size()-1; i++){
			if(ProductParser.getInstance().existFile(machineManager.getDir()
					, productList.get(i).getProductId())){
				product = ProductParser.getInstance().readProduct(machineManager.getDir()
						, productList.get(i).getProductId());
				if(product!=null)
					break;
			}
		}
		if(product==null && i==productList.size()){
			unbindWork();
			return null;
		}
		return product;
	}
	
	protected void unbindWork(){
		work = null;
	}
	
	protected int generateDuration(){
		int duration = ((int)(Math.random() * durationRange))+baseDuration;
		return duration;
	}
	
	protected int generateQuality(){
		int quality = (int)(Math.random()*100);
		return quality;
	}
	
	public abstract void beforeManufacture();
	public abstract void afterManufacture();
}
